﻿using F2B.Orchard.Schedule.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace F2B.Orchard.Schedule.Providers
{
    public class YearlyProvider : DateProvider
    {
        private readonly int _month;
        private readonly int _day;
        private readonly int _startYear;
        private readonly int _yearInterval;
        private readonly TimeSpan _duration;

        private readonly DateTime _startDate;

        public YearlyProvider(SchedulePart part)
        {
            _startYear = part.StartDate.Year;
            _month = part.StartDate.Month;
            _day = part.StartDate.Day;
            _duration = TimeSpan.FromDays(part.DaysIncluded());

            _startDate = part.StartDate;

            _yearInterval = part.RepeatInterval;
        }

        public override IEnumerable<DateTime> Over(DateTime start, DateTime end, bool reverse = false)
        {
            DateTime current;
            int year = start.Year;
            if (year < _startYear)
                year = _startYear;
            else
            {
                var yearsOff = (year - _startYear) % _yearInterval;
                if (yearsOff != 0)
                {
                    year += _yearInterval - yearsOff;
                }
            }

            current = GetDateForYear(year);
            if (current + _duration < start)
            {
                year += _yearInterval;
                current = GetDateForYear(year);
            }
            if (current > end) yield break;

            while (true)
            {
                yield return current;
                year += _yearInterval;
                current = GetDateForYear(year);
                if (current > end) break;
            }
        }

        private DateTime GetDateForYear(int year)
        {
            int day = _day;

            if (_month == 2 && _day == 29)
            {
                // special case for 2/29 -- will be 2/28 on non-leap-years
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
                {
                    day = 28;
                }
            }

            return new DateTime(year, _month, day);
        }
    }
}